//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using OpenLS.Drawing;

namespace OpenLS.Spreadsheet.UI.Internals
{
    public class FillToBrushConverter : IMultiValueConverter
    {
        //internal abstract FillUse FillUse { get; }
        public Brush DefaultBrush { get; set; }
        static Dictionary<Fill, Brush> _backgroundCache = new Dictionary<Fill, Brush>();
        //static Dictionary<Fill, Brush> _foregroundCache = new Dictionary<Fill, Brush>();
        private static ColorScheme _lastColorScheme;

        internal static Brush GetBrush(Fill fill, ColorScheme colorScheme)
        { 
            if (_lastColorScheme != colorScheme)
            {
                _backgroundCache = new Dictionary<Fill, Brush>();
                //_foregroundCache = new Dictionary<Fill, Brush>();
                _lastColorScheme = colorScheme;
            }
            Dictionary<Fill, Brush> dictionary;
            //if (fillUse == FillUse.Background)
                dictionary = _backgroundCache;
            //else
            //{
            //    dictionary = _foregroundCache;
           // }
            if (fill == null)
                return null;
            Brush result;
            if (dictionary.TryGetValue(fill, out result))
                return result;
            result = getBrushImp(colorScheme, fill);
            dictionary.Add(fill, result);
            return result;
        }

        private static Brush getBrushImp(ColorScheme colorScheme, Fill f)
        {
            if (f is PatternFill)
            {
                return getPatternBrush((PatternFill) f, colorScheme);
            }
            if (f is GradientFill)
            {
                return ColorToBrushConverter.GetBrushFromGradient((GradientFill) f, colorScheme);
            }
            //\\
            // Contract.Assert(false);
            Debug.WriteLine("Unable to convert " + f);
            return Brushes.Pink;
        }

        private static Brush getPatternBrush(PatternFill f, ColorScheme colorScheme)
        {
            if (f.Type == PatternType.Solid)
            {
                if (f.ForegroundColor == null)
                    return Brushes.Black;
                return ColorToBrushConverter.GetBrush(f.GetColor(), colorScheme);
                ;
            }
            if (f.Type == PatternType.None)
                return Brushes.Transparent;//\\ ColorToBrushConverter.GetBrush(f.GetColor(), colorScheme); ;
            SolidColorBrush foregroupndBrush = ColorToBrushConverter.GetBrush(f.ForegroundColor, colorScheme);
            SolidColorBrush backgroundBrush = ColorToBrushConverter.GetBrush(f.BackgroundColor, colorScheme);
            return realPatternBrush(f.Type, backgroundBrush, foregroupndBrush);

        }

        private static Brush realPatternBrush(PatternType type, SolidColorBrush backgroundBrush, SolidColorBrush foregroundBrush)
        {
            if (backgroundBrush == null)
                backgroundBrush = Brushes.Transparent;
            if (foregroundBrush == null)
            {
                switch (type)
                {
                    case PatternType.Solid:
                        case PatternType.None:
                        foregroundBrush = Brushes.Transparent;
                        break;
                    default:
                        foregroundBrush = Brushes.Black;
                        break;
                }
            }
            Color newColor = Color.FromArgb((byte) ((backgroundBrush.Color.A + foregroundBrush.Color.A) / 2),
                                            (byte) ((backgroundBrush.Color.R + foregroundBrush.Color.R) / 2),
                                            (byte) ((backgroundBrush.Color.G + foregroundBrush.Color.G) / 2),
                                            (byte) ((backgroundBrush.Color.B + foregroundBrush.Color.B) / 2))
                ;
            ;
            return new SolidColorBrush(newColor);
            DrawingGroup group = new DrawingGroup();
            group.Children.Add(new GeometryDrawing(backgroundBrush, null, new RectangleGeometry(new Rect(0, 0, 2, 2))));
            group.Children.Add(new GeometryDrawing(foregroundBrush, null, new RectangleGeometry(new Rect(0, 0, 2, 1))));
            DrawingBrush result = new DrawingBrush(group);
            result.ViewportUnits = BrushMappingMode.Absolute;
            result.Viewport = new Rect(0, 0, 2, 2);
            result.TileMode = TileMode.Tile;
            return result;
        }

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            Fill fill = StrictConverter.Convert<Fill>(values[0]);
            if (fill == null )
                return DefaultBrush     ;
            ColorScheme colorScheme = StrictConverter.Convert<ColorScheme>(values[1]);
            var result =  GetBrush(fill, colorScheme);
            if (result == null )
                result = DefaultBrush;
            return result;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }

       /* internal static Brush GetBrush(Fill fill, ColorScheme colorScheme)
        {
            return GetBrush(fill, colorScheme);
        }*/
    }

    public sealed class FillToBackgroundBrushConverterobsolete : FillToBrushConverter
    {
        #region IMultiValueConverter Members

        #endregion
    }
}